package deng.quartz;

import java.util.Arrays;
import java.util.Properties;

import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.impl.StdSchedulerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Start a Quartz service that configured as RMI+Registry (server) and wait for shutdown (CTRL+C).
 * 
 * Usage: java QuartzServer <quartz.properties>
 */
public class QuartzServer
{
	/** A slf4j logger. */
	private static Logger logger = LoggerFactory.getLogger(QuartzServer.class);
	
	private QuartzService quartzService;
	
	public QuartzServer(String[] args)
	{
		initInstance(args);
	}
	private void initInstance(String[] args)
	{
		logger.debug("Parsing args: " + Arrays.asList(args));
		
		// Create quartzService with first args as config.
		Properties props = Utils.loadProperties(args[0]);
		try {
			StdSchedulerFactory schedulerFactory = new StdSchedulerFactory(props);
			Scheduler scheduler = schedulerFactory.getScheduler();
			logger.debug("Creating quartzService with " + scheduler);
			quartzService = new QuartzService();
			quartzService.setScheduler(scheduler);
		} catch (SchedulerException e) {
			throw new RuntimeException(e);
		}
	}
	
	public void run()
	{
		start();
		registerShutdownEvent();
		waitForShutdownEvent();
	}
		
	public void start()
	{
		quartzService.start();
	}
	
	public void stop()
	{
		quartzService.stop();
	}
	
	private void waitForShutdownEvent()
	{
		logger.debug("Wait and block current thread.");
		synchronized(this) {
			try {
				this.wait();
			} catch (InterruptedException e) {
				throw new RuntimeException(e);
			}
		}
	}
	private void notifyShutdownEvent()
	{
		logger.debug("Notify all waiting thread.");
		synchronized(this) {
			this.notifyAll();
		}
	}

	private void registerShutdownEvent()
	{
		logger.debug("Registering a shutdown event with Java Runtime#shutdownHook.");
		Runtime.getRuntime().addShutdownHook(new Thread(){
			
			@Override
			public void run()
			{	
				logger.debug("Shutdown started.");
				QuartzServer.this.stop();
				notifyShutdownEvent();
			}
			
		});
	}

	public static void main(String[] args)
	{
		QuartzServer main = new QuartzServer(args);
		main.run();
	}

}
